/* 
 * Simulation recorder
 * 
 * Anas Nasarullah
 * 
 * Jul 2013
 * 
 * Records user events on frontend UI in order to simulate the same action
 * 
 * Dependencies : 
 * - Xdotool for simulation
 * - Prototype JS 
 * 
 */

var SimuRec = Class.create();

SimuRec.prototype = {
    
    initialize : function() {
       if(this.isSupported()) {
            this.recorded_moves = '';
            this.is_recording   = false; 
            
            this.save_url       = 'http://localhost/SimuRec/simurec/dump_rec.php/';
           
            //adds buttons on body for recording control
            this.createControls();                                    
            this.addControls();                                    
            this.observeEvents();  
                        
       }
    },

    //check browser support
    isSupported : function() {
        //Check for platform support
        if( Prototype.Browser.IE || Prototype.Browser.Gecko || Prototype.Browser.WebKit ) {
        	if(navigator.appName === 'Microsoft Internet Explorer' && 
  			  ( (navigator.appVersion.search('MSIE 6') > -1) || (navigator.appVersion.search('MSIE 7') > -1) )) {
  			    return false;
  			}
              	
          	var uagent = navigator.userAgent.toLowerCase();

          	if( (uagent.search("iphone") > -1) || (uagent.search("ipod") > -1) || (uagent.search("ipad") > -1) || (uagent.search("android") > -1)  ) {
          		return false;
          	}
            return true;
        }

        return false;
    },
            
    createControls : function() {
        body                = document.getElementsByTagName('body');

        span                = document.createElement('span');
        span.className      = 'simurec-container';
        span.id             = 'simurec-container';
        
        btn_rec             = document.createElement('button');
        btn_rec.type        = 'button';
        btn_rec.className   = 'simurec-recbtn';
        btn_rec.id          = 'simurec-recbtn';
        btn_rec.innerHTML   = 'Record';
        
        btn_stp             = document.createElement('button');
        btn_stp.type        = 'button';
        btn_stp.className   = 'simurec-stpbtn';
        btn_stp.id          = 'simurec-stpbtn';
        btn_stp.innerHTML   = 'Stop';
        
        btn_ply             = document.createElement('button');
        btn_ply.type        = 'button';
        btn_ply.className   = 'simurec-plybtn';
        btn_ply.id          = 'simurec-plybtn';
        btn_ply.innerHTML   = 'Save';
        
        span.appendChild(btn_rec);
        span.appendChild(btn_stp);
        span.appendChild(btn_ply);
        
        if(body[0] !== undefined) {
            body[0].appendChild(span);
        }
    },
            
    addControls : function() {
        
        //Adds control events to buttons
        Event.observe( $('simurec-recbtn'), 'click', this.startRecording.bind(this));
        
        Event.observe( $('simurec-stpbtn'), 'click', this.stopRecording.bind(this));
        
        Event.observe( $('simurec-plybtn'), 'click', this.saveRecording.bind(this));                
        
    },
            
    observeEvents : function() {
        Event.observe(document, 'click', this.recordClickEvents.bind(this));
        //Event.observe(document, 'mouseover', this.recordEvents.bind(this));
        Event.observe(document, 'keyup', this.recordKeyEvents.bind(this));
        
        //Finally an event to save user data when they move away from the page        
        Event.observe(window, 'beforeunload', this.saveRecording.bind(this));
    },
            
    recordClickEvents : function(e) {
        
        element = Event.element(e);

        if(this.is_recording === true && !this.isSelfClick(element) ) {
            positionY = ((window.outerHeight - window.innerHeight) + (e.pageY + window.screenY) );
            positionX = (window.screenX + e.pageX);                

            this.addNewEvent('mousemove --sync '+positionX+' '+positionY);
            this.addNewEvent('click 1');
        }
    },
            
    recordKeyEvents : function(e) {   
        element = Event.element(e);

        if(this.is_recording === true && !this.isSelfClick(element) ) {
            elem = Event.element(e);

            this.addNewEvent('type '+elem.value);
        }
    },
            
    startRecording : function() {
        this.is_recording = true;
    }, 
    
    stopRecording : function() {
        this.is_recording = false;
    },
    
    saveRecording : function () {      
        //var mainObject = this;        
        new Ajax.Request(this.save_url, {
            method:     'post',
            parameters: '&rec='+this.recorded_moves,
            onSuccess:  function(xhr) {
                //return mainObject.successCallback();
                alert('saved');
            },
            onFailure: function(){alert('Failed to save records.');}
        });
        
        alert('Please wait... saving events.');
    },
            
    addNewEvent : function(line) {
        this.recorded_moves += line;        
        this.recorded_moves += "\n";
    },
    
    isSelfClick : function(element) {
        if( element.id === 'simurec-recbtn' || element.id === 'simurec-stpbtn' || element.id === 'simurec-plybtn' ) {
            return true;
        }
        
        return false;
    }
    
}

/*TODO : 
 * 
 * - Cookie to save cross page recording
 *   + Event to know when moving away from a page 1) save current recordings and set cookie flag to cont from there
 * 
 * - Saving file from JS > AJAX req to PHP and execute xdotool from there?
 *   + UPDATE : can only save file which needs to be manually executed
 *   
 * - Is it possible to simulate from JS? - currently not possible
 * 
 * - Browser recognition in order to select right window
 * */

/*Known Issues : 
 * 
 * - Messes up height when firebug or any debugger open in window
 **/

/**
 * Testing Requirement
 * 
 * - When replaying move to the original state of flow (if logged in during testing please log out and start with a fresh state)
 * - Have firebugs and other debuggers minimized
 * - Doesn't supports replicating scrolling for now so better stick to one view.
 */
